package com.its.system.algotithm.class03;

import java.util.Stack;

/**
 * 如何使用栈 实现队列
 *
 * 队列先进先出
 * 栈 先进后出
 *
 * 两个栈互相导, push栈, pop栈
 *  当用户想要数据的时候, 你把push栈里的数据导到pop栈里去, 从pop栈里给用户返回
 *  两个原则:
 * 	1.push栈导数据到pop栈一定要一次性倒完
 * 	2.pop栈里有数据, 不能从push栈导数据(只有pop栈空了才可以导数据)
 * 	导数据的行为，既可以被封装到加一个数之后，看能不能倒也可以被封装到用户想要一个数再给用户之前，
 * 	看能不能倒也可以封装在 peek 检查这个行为看能不能导数据你在任何时刻都可以导数据，只要遵循两点原则，你怎么都对
 */
public class Code06_TwoStacksImplementQueue {

	public static class TwoStacksQueue {
		// 添加数据的栈
		public Stack<Integer> stackPush;
		public Stack<Integer> stackPop;

		public TwoStacksQueue() {
			stackPush = new Stack<Integer>();
			stackPop = new Stack<Integer>();
		}

		// push栈向pop栈倒入数据
		private void pushToPop() {
			if (stackPop.isEmpty()) {
				while (!stackPush.isEmpty()) {
					stackPop.push(stackPush.pop());
				}
			}
		}

		/**
		 * 添加数据
		 * @param pushInt
		 */
		public void add(int pushInt) {
			stackPush.push(pushInt);
			//添加完毕之后就看能不能到数据
			pushToPop();
		}

		/**
		 * 取数据
		 * @return
		 */
		public int poll() {
			if (stackPop.empty() && stackPush.empty()) {
				throw new RuntimeException("Queue is empty!");
			}
			//先检查能不能导数据
			pushToPop();
			//取数据
			return stackPop.pop();
		}

		public int peek() {
			if (stackPop.empty() && stackPush.empty()) {
				throw new RuntimeException("Queue is empty!");
			}
			pushToPop();
			return stackPop.peek();
		}
	}

	public static void main(String[] args) {
		TwoStacksQueue test = new TwoStacksQueue();
		test.add(1);
		test.add(2);
		test.add(3);
		System.out.println(test.peek());
		System.out.println(test.poll());
		System.out.println(test.peek());
		System.out.println(test.poll());
		System.out.println(test.peek());
		System.out.println(test.poll());
	}

}
